package com.circle.interests.biz.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.circle.common.core.exception.RRException;
import com.circle.interests.biz.constants.Constants;
import com.circle.interests.biz.entity.PrizeGameInventory;
import com.circle.interests.biz.entity.PrizeHonglianProduct;
import com.circle.interests.biz.mapper.PrizeGameInventoryMapper;
import com.circle.interests.biz.service.IPrizeGameInventoryService;
import com.circle.interests.biz.service.IPrizeHonglianProductService;
import com.circle.prize.library.api.dto.game.PrizeGameInventoryDto;
import com.circle.prize.library.api.enums.InventoryTypeEnum;
import com.circle.prize.library.api.enums.PrizeTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 奖品库存 服务实现类
 * </p>
 *
 * @author generator
 * @since 2021-12-17
 */
@Slf4j
@Service
public class PrizeGameInventoryServiceImpl extends ServiceImpl<PrizeGameInventoryMapper, PrizeGameInventory> implements IPrizeGameInventoryService {

    @Resource
    private RedissonClient redissonClient;
    @Resource
    private IPrizeHonglianProductService prizeHonglianProductService;

    @Override
    public boolean saveGameInventory(Integer sceneType, String sceneId, List<PrizeGameInventoryDto> prizeInventoryList) {
        if (CollectionUtil.isEmpty(prizeInventoryList)) {
            return true;
        }
        List<PrizeGameInventory> entityList = new ArrayList<>();
        for (PrizeGameInventoryDto inventoryDto : prizeInventoryList) {
            // 校验库存类型
            if (InventoryTypeEnum.getByCode(inventoryDto.getInventoryType()) == null) {
                throw new RRException("库存类型错误");
            }
            // 校验奖品类型
            if (PrizeTypeEnum.getByCode(inventoryDto.getPrizeType()) == null) {
                throw new RRException("奖品类型错误");
            }
            if (Objects.equals(inventoryDto.getPrizeType(), 3)) {
                PrizeHonglianProduct prizeHonglianProduct = prizeHonglianProductService.getByProductCode(inventoryDto.getProductCode());
                if (prizeHonglianProduct == null) {
                    throw new RRException("鸿联商品未配置");
                }
            }
            PrizeGameInventory entity = getOne(Wrappers.lambdaQuery(PrizeGameInventory.class)
                    .eq(PrizeGameInventory::getSceneType, sceneType)
                    .eq(PrizeGameInventory::getSceneId, sceneId)
                    .eq(PrizeGameInventory::getPrizeCode, inventoryDto.getPrizeCode()).last("limit 1"));
            if (entity == null) {
                entity = new PrizeGameInventory();
            }
            entity.setSceneType(sceneType);
            entity.setSceneId(sceneId);
            entity.setPrizeCode(inventoryDto.getPrizeCode());
            entity.setPrizeType(inventoryDto.getPrizeType());
            entity.setProductCode(inventoryDto.getProductCode());
            entity.setInventoryType(inventoryDto.getInventoryType());
            entity.setTotal(inventoryDto.getTotal());
            entityList.add(entity);
        }
        super.saveOrUpdateBatch(entityList);
        get(sceneType, sceneId, true);
        return Boolean.TRUE;
    }

    @Override
    public PrizeGameInventory get(Integer sceneType, String sceneId, String prizeCode) {
        return get(sceneType, sceneId, false).stream()
                .filter(item -> item.getPrizeCode().equals(prizeCode)).findAny().orElseThrow(() -> new RRException("奖品不存在"));
    }

    private RList<PrizeGameInventory> get(Integer sceneType, String sceneId, boolean forceRefresh) {
        String key = String.format(Constants.PRIZE_INFO_CACHE_KEY, sceneType, sceneId);
        RList<PrizeGameInventory> rList = redissonClient.getList(key);
        if (!rList.isExists() || forceRefresh) {
            List<PrizeGameInventory> list = list(Wrappers.lambdaQuery(PrizeGameInventory.class)
                    .eq(PrizeGameInventory::getSceneType, sceneType).eq(PrizeGameInventory::getSceneId, sceneId));
            if (CollectionUtil.isNotEmpty(list)) {
                rList.clear();
                rList.addAll(list);
                rList.expire(1, TimeUnit.DAYS);
            }
        }
        return rList;
    }

}
